<?php
class Prod_movstock extends MY_Controller {

	public function __construct()
    {
    	# Al constructor le envío la clase Controlador, y el nombre de la entidad gestionada
    	parent::__construct(get_class($this), 'Prod_stock');

    	$this->title = 'Productos :: Movimientos de Stock';
		$this->CARPETA_VISTAS = 'productos/';
		$this->nombre_entidad = 'Movimiento de Stock';
		$this->nombre_entidad_plural = 'Movimientos de Stock';

		$this->pagina_ver = $this->CARPETA_VISTAS . 'stock_ver_todos_view';
		$this->pagina_editar = $this->CARPETA_VISTAS . 'stock_edit_view';
		$this->pagina_filtros_ver = $this->CARPETA_VISTAS . 'stock_filtros_ver_todos_view';

		$this->pagina_ayuda = $this->template->getCarpetaAyuda() . 'ayuda_stock';
	}


	/* IMPORTANTE: DEBE existir esta función. 
	 * Crea un objeto de la entidad correspondiente y lo pobla con la información obtenida a 
	 * partir del formulario recibido a través de POST.	*/
	protected function getObjetoDesdeForm()
	{
		$idEntidad = is_numeric($this->input->post('txt_id')) ? $this->input->post('txt_id') : NULL;
		
		// Sólo puede elegir UNA de las opciones
		$prod_id = NULL; $moto_id = NULL;
		$opcionElegida = $this->input->post('f_opt_producto');
		if($opcionElegida == 1) $prod_id = $this->input->post('txt_prod_id');
		else $moto_id = $this->input->post('txt_moto_id');

		$this->load->library('util_stock');
		$objEntidad = $this->util_stock->cargarStock($idEntidad,
													   parent::fechaFormatoBD($this->input->post('txt_fecha')),
													   $this->input->post('txt_cantidad'),
													   $this->input->post('txt_costo_unitario'),
													   $this->input->post('txt_lote'),
													   $this->input->post('txt_numeroSerie'),
													   $this->input->post('txt_observaciones'),
													   0,
													   $prod_id,
													   $moto_id,
													   $this->input->post('sel_origen'),
													   $this->input->post('sel_deposito'),
													   $this->input->post('f_txt_moneda_id'),
													   $_SESSION[$this->template->getUsernameSessionName()],
													   $this->input->post('sel_unidad_negocio'),
													   $this->input->post('sel_proveedor'));

        $objOrigen = new Prod_origen($objEntidad->prod_origen_id);
        $objDeposito = new Prod_deposito($objEntidad->prod_deposito_id);
        $objDivisa = new Div_divisa($objEntidad->div_divisa_id);
        $objProveedor = new Persona($objEntidad->persona_id);
		
		$datos['objEntidad'] = $objEntidad;
		$datos['objRelacionados'] = array($objOrigen, $objDeposito, $objDivisa, $objProveedor);

		return $datos;
	}

	public function getCostoProducto($id_origen, $id_producto, $id_proveedor, $es_producto = TRUE){
		if($es_producto) $objProducto = new Prod_producto($id_producto);
        else {
        	$objMoto = new Prod_moto($id_producto);
        	$objProducto = $objMoto->prod_producto->get();
        }
		$objOrigen = new Prod_origen($id_origen);

		// Se define en base a la información del sistema, cuál sería el costo propuesto del producto
		// Prioridad: costo asignado en el producto
		$costo_propuesto = $objProducto->costo;
		if($costo_propuesto == 0) {
			if($id_proveedor != 0) {
				// Si no está definido el costo del producto, busco el precio del mismo según el proveedor
				$prov_relacionado = $objProducto->prod_proveedor_producto->where('persona_id', $id_proveedor)->get();
				$costo_propuesto = $prov_relacionado->importe_pesos;
			}
			else {
				// Si no se hubiera especificado el proveedor, busco el precio según el favorito,
				// Si no tuviera un favorito, obtengo el precio entre todos los proveedores
				$precio_prov_favorito = 0;
				$precio_mas_bajo = $precio_mas_alto = $objProducto->prod_proveedor_producto->get()->importe_pesos;
				foreach ($objProducto->prod_proveedor_producto->get_iterated() as $prov_prod) {
					if($prov_prod->favorito) $precio_prov_favorito = $prov_prod->importe_pesos;
					else {
						if ($prov_prod->importe_pesos < $precio_mas_bajo) $precio_mas_bajo = $prov_prod->importe_pesos;
						if ($prov_prod->importe_pesos > $precio_mas_alto) $precio_mas_alto = $prov_prod->importe_pesos;
					}
				}

				if ($precio_prov_favorito != 0) $costo_propuesto = $precio_prov_favorito;
				else {
					if ($objOrigen->es_ingreso) $costo_propuesto = $precio_mas_bajo;
					else $costo_propuesto = $precio_mas_alto;
				}
			}
		}

		$margen_propuesto = 0;
		if (!$objOrigen->es_ingreso) {
			// Se trata de una salida, debo calcular el margen de ganancia
			// Prioridad: margen asignado en el producto
			$margen_propuesto = $objProducto->margen_ganancia;
			if($margen_propuesto == 0) {				
				if($id_proveedor != 0) {
					$prov_relacionado = $objProducto->prod_proveedor_producto->where('persona_id', $id_proveedor)->get();
					$margen_propuesto = $prov_relacionado->persona->get()->margen_ganancia;
				}
				else {
					$margen_favorito = 0;
					$margen_no_favorito = $objProducto->prod_proveedor_producto->persona->get()->margen_ganancia;
					foreach ($objProducto->prod_proveedor_producto->get_iterated() as $prov_prod) {
						$margen_prov = $prov_prod->persona->get()->margen_ganancia;
						if($prov_prod->favorito) $margen_favorito = $margen_prov;
						else {
							if($margen_prov > $margen_no_favorito) $margen_no_favorito = $margen_prov;
						}
					}

					if ($margen_favorito != 0) $margen_propuesto = $margen_favorito;
					else $margen_propuesto = $margen_no_favorito;
				}
			}
		}

		$costo_total = $costo_propuesto * (1 + ($margen_propuesto / 100));
		if($this->input->is_ajax_request()) echo $costo_total;
		else return $costo_total;
	}

	/* IMPORTANTE: DEBE existir esta función. 
	 * Carga en el arreglo que luego se pasarán a las vistas, los datos correspondientes a otras entidades que se
	 * necesiten. Por ejemplo, en este método deben cargarse las entidades a las que puede asociarse o relacionarse
	 * la entidad actual. Si no se requiriesen, no se agrega nada. */
	protected function cargarDatosRelacionados($dataView)
	{
		$this->load->library('util_unidad');
		$dataView['listado_unidades'] = $this->util_unidad->getPorUsuario($_SESSION[$this->template->getIdUserSessionName()]);

		$obj_deposito = new Prod_deposito();
		$dataView['listado_depositos'] = $obj_deposito->get_iterated();

		$obj_origen = new Prod_origen();
		$obj_origen->where('es_manual', TRUE);
		$dataView['listado_origenes'] = $obj_origen->get_iterated();

		return $dataView;
	}

	public function guardar()
	{
		$this->load->library('util_stock');
		
		$datos = $this->getObjetoDesdeForm();
		$dataView = $this->util_stock->guardar($datos);
		if(!empty($dataView['error'])) {
			// Falló el intento de guardar
			$this->_cargarFormEdicion($dataView, TRUE); 
		}
		else { $this->ver_todos($dataView); }
	}

	/* IMPORTANTE: DEBE existir esta función. 
	 * Obtiene el listado de elementos de acuerdo a los filtros que se hayan establecido y enviado a través
	 * del método POST. Devuelve un detalle de los filtros aplicados (o vacío si no hubiera filtros)	*/	
	protected function _aplicarFiltros($dataView = array())
	{
		// Creo un objeto del modelo, para poblarlo con los datos que necesito mostrar
		$objEntidad = $this->getObjeto();
		$detalle_filtros = '';

		# Siempre filtro lo que se muestra según las unidades de negocio asociadas al usuario logueado
		$this->load->library('util_unidad');
		$objEntidad = $this->util_unidad->filtrarListado($objEntidad, $_SESSION[$this->template->getIdUserSessionName()], $this->input->post('f_sel_unidad'));

		$unidades = $this->input->post('f_sel_unidad');
		if(is_array($unidades) && count($unidades) > 0) {
			$objEntidad->where_in('conf_unidad_negocio_id', $unidades);
		}

		$fecha_desde = parent::fechaFormatoBD($this->input->post('f_txt_fecha_desde'));
		if(!empty($fecha_desde)) {
			$objEntidad->where('fecha >=', $fecha_desde); 
			$detalle_filtros .= (!empty($detalle_filtros) ? ' | ' : '') . 'Fecha desde ' . $fecha_desde;
		}

		$fecha_hasta = parent::fechaFormatoBD($this->input->post('f_txt_fecha_hasta'));
		if(!empty($fecha_hasta)) {
			$objEntidad->where('fecha <=', $fecha_hasta); 
			$detalle_filtros .= (!empty($detalle_filtros) ? ' | ' : '') . 'Fecha hasta ' . $fecha_hasta;
		}

		$prod_cod = $this->input->post('f_txt_codigo_prod');
		if(!empty($prod_cod)) {
			$objEntidad->like_related_prod_producto('codigo', $prod_cod); 
			$detalle_filtros .= (!empty($detalle_filtros) ? ' | ' : '') . 'Cód. Producto ' . $prod_cod;
		}

		$moto_serie = $this->input->post('f_txt_serie_moto');
		if(!empty($moto_serie)) {
			$objEntidad->where_related_prod_moto('numeroSerie', $moto_serie); 
			$detalle_filtros .= (!empty($detalle_filtros) ? ' | ' : '') . 'N° Serie Moto ' . $moto_serie;
		}

		$origen_id = $this->input->post('f_sel_origen');
		if($origen_id != 0) {
			$objEntidad->where('prod_origen_id', $origen_id); 
			$detalle_filtros .= (!empty($detalle_filtros) ? ' | ' : '') . 'Origen';
		}

		$deposito_id = $this->input->post('f_sel_deposito');
		if($deposito_id != 0) {
			$objEntidad->where('prod_deposito_id', $deposito_id); 
			$detalle_filtros .= (!empty($detalle_filtros) ? ' | ' : '') . 'Depósito';
		}

		$dataView['objEntidad'] = $objEntidad;
		$dataView['detalle_filtros'] = $detalle_filtros;

		return $dataView;
	}

	/* IMPORTANTE: DEBE existir esta función.
	 * Valida las condiciones que deben cumplirse para que un elemento pueda ELIMINARSE. */
	protected function validarEliminacion($id_elemento)
	{
		return FALSE;
	}

	/* IMPORTANTE: DEBE existir esta función.
	 * Valida las condiciones que deben cumplirse para que un elemento pueda EDITARSE. */
	protected function validarEdicion($id_elemento)
	{
		if($id_elemento == NULL || $id_elemento == 0) return TRUE;
		else return FALSE;
	}

	public function generar_excel()
	{
		// Obtengo el listado según los filtros definidos por el usuario
		$vector = array();
		$vector['realizar_paginacion'] = FALSE;
		$vector = $this->filtrar($vector);
		$listado = $vector['listado'];
		
		$datos = array();
		// Recorro el listado y genero los datos que necesito
		foreach ($listado as $objEntidad) {
			$objEntidad->prod_origen->get();
			$objEntidad->prod_deposito->get();
			$objEntidad->div_divisa->get();

			$objProducto;
			$descri_prod = ''; $descri_moto = '';
			if($objEntidad->prod_moto->exists()){
				$objEntidad->prod_moto->get();
				$objProducto = $objEntidad->prod_moto->prod_producto->get();
				$descri_moto = 'N° Serie: ' . $objEntidad->prod_moto->numeroSerie;
			}
			else $objProducto = $objEntidad->prod_producto->get();

			$descri_prod = 'Producto: (' . $objProducto->codigo . ') ' . $objProducto->nombre;
			if($descri_moto != '') $descri_prod .= '. ' . $descri_moto;

			$unidadNeg = $objEntidad->getUnidadNegocio()->nombre;

			$datos[] = array($objEntidad->fecha,
							$objEntidad->prod_origen->descripcion,
							$descri_prod,
							$objEntidad->cantidad,
							$objEntidad->div_divisa->simbolo,
							$objEntidad->costo_unitario,
							$objEntidad->prod_deposito->nombre, 
							$unidadNeg
							);
		}
		
		$dataView['datos_a_exportar'] = $datos;
		$dataView['headers_datos'] = array('Fecha', 'Origen', 'Producto', 'Cantidad', '', 'Costo Unitario', 'Depósito', 'Unidad de Negocio');

		parent::generar_excel($dataView);
	}
}